﻿using S22.Imap;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net.Mail;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace GetEmailAttachment
{
    public partial class frmMain : Form
    {
        private bool IsCancelDownLoad = false;
        public frmMain()
        {
            InitializeComponent();
            prgWaiting.CancelAction = new Action(() => { bgkGetMail.CancelAsync(); IsCancelDownLoad = true; });
        }

        private void btnBeginSearch_Click(object sender, EventArgs e)
        {
            SaveConfig();
            bgkGetMail.RunWorkerAsync();
        }

        private void btnSelectFolder_Click(object sender, EventArgs e)
        {
            using (FolderBrowserDialog dlg = new FolderBrowserDialog() { DirectoryPath = txtSaveFolder.Text })
            {
                if (dlg.ShowDialog(this) == DialogResult.OK)
                {
                    txtSaveFolder.Text = dlg.DirectoryPath;
                }
            }
        }

        private void bgkGetMail_DoWork(object sender, DoWorkEventArgs e)
        {
            string account = ""
                , passWord = ""
                , imapServer = ""
                , mailStatu = ""
                , subStr = ""
                , fromStr = ""
                , mailbox="";
            int port = 993;
            this.Invoke(new Action(() =>
            {
                account = txtAccount.Text;
                passWord = txtPassCode.Text;//获得的授权码
                imapServer = cboImapServer.Text;
                port = Convert.ToInt32(txtImapPort.Text);
                mailStatu = cboMailStatu.Text;
                subStr = txtMailSubject.Text.Trim();
                fromStr = txtFrom.Text.Trim();
                mailbox = cboFolder.Text.Trim();
                if (mailbox == "")
                    mailbox = null;
            }));

            try
            {
                using (ImapClient client = new ImapClient(imapServer, port, account, passWord, AuthMethod.Login, true))
                {
                    SearchCondition a = SearchCondition.All();
                    if (mailStatu == "已读")
                    {
                        a = SearchCondition.Seen();
                    }
                    else if (mailStatu == "未读")
                    {
                        a = SearchCondition.Unseen();
                    }
                    a.And(SearchCondition.Subject(txtMailSubject.Text.Trim())).And(SearchCondition.From(txtFrom.Text.Trim()));
                    uint[] uids = client.Search(a, mailbox) as uint[];
                    this.Invoke(new Action(() =>
                    {
                        prgWaiting.Maximum = uids.Length;
                        prgWaiting.Value = 0;
                        SetWaiting(true);
                    }));
                    List<SearchResult> results = new List<SearchResult>();
                    foreach (uint id in uids)
                    {
                        if (bgkGetMail.CancellationPending)
                        {
                            break;
                        }
                        MailMessage mm = client.GetMessage(id, mailbox: mailbox);
                        this.Invoke(new Action(() =>
                        {
                            prgWaiting.Value += 1;
                        }));
                        if (mm != null)
                        {
                            if (subStr != "" && !mm.Subject.ToString().Contains(subStr))
                            {
                                continue;
                            }
                            if (fromStr != "" && !mm.From.ToString().Contains(fromStr))
                            {
                                continue;
                            }
                            results.Add(new SearchResult(mm));
                        }
                    }
                    e.Result = results.Where(p => p.From != null).ToList();
                }
            }
            catch (Exception ex)
            {
                e.Result = $"---------服务器连接错误:{0}------------" + ex.Message;
            }
        }
        private void SetWaiting(bool IsShow)
        {
            this.Controls.Cast<Control>().ToList().ForEach((p) =>
            {
                p.Enabled = !IsShow;
            });
            prgWaiting.Visible = IsShow;
            prgWaiting.Enabled = IsShow;
        }

        private void bgkGetMail_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Result is List<SearchResult>)
            {
                grdSearchData.DataSource = e.Result;
            }
            else
            {
                string error = e.Result?.ToString();
                MessageBox.Show(error, "错误");
            }
            SetWaiting(false);
        }

        private void btnDownLoadAll_Click(object sender, EventArgs e)
        {
            DownLoadAttas();
        }

        private void btnDownLoadSelected_Click(object sender, EventArgs e)
        {
            DownLoadAttas(true);
        }
        private void DownLoadAttas(bool DownLoadSelected = false)
        {
            var data = grdSearchData.DataSource as List<SearchResult>;
            if (data == null || data.Count == 0)
            {
                MessageBox.Show("没有可下载的内容!", "提示");
            }
            else
            {
                if (DownLoadSelected)
                {
                    data = data.Where(p => p.Selected).ToList();
                    if (data.Count == 0)
                    {
                        MessageBox.Show("请先选中数据！", "提示");
                        return;
                    }
                }
                string folder = txtSaveFolder.Text;
                if (folder == "")
                {
                    MessageBox.Show("请先选择保存路径！");
                    return;
                }
                FileHelper.CreateFile("log.txt");
                int count = data.Sum(p => p.AttachmentsCount ?? 0);
                SetWaiting(true);
                prgWaiting.Maximum = count;
                prgWaiting.Value = 0;
                IsCancelDownLoad = false;
                Thread th = new Thread(() =>
                {
                    data.ForEach((p) =>
                    {
                        if (!IsCancelDownLoad)
                            p.DownLoadAttachments(folder, new Action(() => { prgWaiting.Invoke(new Action(() => { prgWaiting.Value += 1; })); }));
                    });
                    bool HasError = data.FirstOrDefault(p => p.HasError) != null;
                    this.BeginInvoke(new Action(() =>
                    {
                        MessageBox.Show($"下载完成{(HasError ? "但有错误" : "")}，请查看！", "提示");
                        SetWaiting(false);
                        if (HasError)
                            System.Diagnostics.Process.Start("log.txt");
                    }));
                })
                { IsBackground = true };
                th.Start();
            }
        }

        private void btnHelp_Click(object sender, EventArgs e)
        {
            string helemsg = @"授权码获取方式:
登录qq邮箱->点击网页上方[设置]->账户->开启IMAP/SMTP服务->获取授权码;
企业邮箱直接输入密码即可！";
            MessageBox.Show(helemsg, "帮助");
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            cboMailStatu.SelectedIndex = 0;
            txtMailSubject.Text = "";
            txtFrom.Text = "";
        }
        private void grdSearchData_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            DataGridView view = sender as DataGridView;
            if (view == null)
                return;
            Rectangle rectangle = new Rectangle(e.RowBounds.Location.X,
                e.RowBounds.Location.Y,
                view.RowHeadersWidth - 4,
                e.RowBounds.Height);
            TextRenderer.DrawText(e.Graphics, (e.RowIndex + 1).ToString(),
                view.RowHeadersDefaultCellStyle.Font,
                rectangle,
                view.RowHeadersDefaultCellStyle.ForeColor,
                TextFormatFlags.VerticalCenter | TextFormatFlags.Right);
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            ReadConfig();
        }
        private void ReadConfig()
        {
            string serverIndex = ConfigHelper.GetAppConfig("ImapServerIndex");
            try
            {
                cboImapServer.SelectedIndex = Convert.ToInt32(serverIndex);
            }
            catch
            {
                cboImapServer.SelectedIndex = 0;
            }
            txtAccount.Text = ConfigHelper.GetAppConfig("Account");
            //txtPassCode.Text = ConfigHelper.GetAppConfig("Password");
            txtSaveFolder.Text = ConfigHelper.GetAppConfig("SaveFolder");
        }
        private void SaveConfig()
        {
            ConfigHelper.SetKeyValue("ImapServerIndex", cboImapServer.SelectedIndex.ToString());
            ConfigHelper.SetKeyValue("Account", txtAccount.Text);
            //ConfigHelper.SetKeyValue("Password", txtPassCode.Text);
            ConfigHelper.SetKeyValue("SaveFolder", txtSaveFolder.Text);
        }

        private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                SaveConfig();
            }
            catch (Exception ex)
            {
                string logpath = "log.txt";
                FileHelper.CreateFile(logpath, false);
                FileHelper.WriteLineToTxt("log.txt", $"error-保存配置-{ DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") }:{ex.Message}  ");
            }
        }

        private void btnGetMailBoxs_Click(object sender, EventArgs e)
        {
            string account = ""
                , passWord = ""
                , imapServer = ""
                , mailStatu = ""
                , subStr = ""
                , fromStr = "";
            int port = 993;
            this.Invoke(new Action(() =>
            {
                account = txtAccount.Text;
                passWord = txtPassCode.Text;//获得的授权码
                imapServer = cboImapServer.Text;
                port = Convert.ToInt32(txtImapPort.Text);
                mailStatu = cboMailStatu.Text;
                subStr = txtMailSubject.Text.Trim();
                fromStr = txtFrom.Text.Trim();
            }));

            try
            {
                using (ImapClient client = new ImapClient(imapServer, port, account, passWord, AuthMethod.Login, true))
                {
                    var mailboxs = client.ListMailboxes().ToList();
                    mailboxs.Insert(0, "");
                    cboFolder.DataSource = mailboxs;
                    cboFolder.DroppedDown = true;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"---------服务器连接错误:{0}------------" + ex.Message,"提示");
            }
        }
    }
}
